/**
 * 相关终端设备弹框详情
 */
Vue.component('dp-mark-dialog', {
    template: `
    <el-dialog 
        :title="param.terminal_name||param.terminalName||'终端详情'"
         class="dp-mark-dialog__wrapper" 
         custom-class="dp-mark-dialog"
         :visible.sync="dialogShow" 
         :width="curComp.width"
         append-to-body>
        <div class="device-dialog-info">
            <p v-for="(item, index) in terminalInfoList" :key="index">{{item.label}}：<span :title="item.value">{{item.value}}</span></p>
        </div>
       <component :is="curComp.name" v-bind="param" v-if="dialogShow"></component>
    </el-dialog>`,
    props: {
        visible: {type: Boolean, default: true},
        terminalType: {type: [Number, String]},     // 终端类型
        terminalId: {type: [Number, String]},       // 终端id
        terminalSerial: {type: [String]},           // 终端序列号
        param: {type: Object, default: () => ({})}  // 相关参数
    },
    data() {
        return {
            dialogShow: false,
        }
    },
    computed: {
        // 设备序列号
        terminalSerial() {
            return this.param.terminalSerial || this.param.terminal_serial
        },

        // 当前使用的弹框组件
        curComp() {
            const enums = [
                {type: '墒情,气象站相关', value: [20, 52, 57, 63, 35], comp: 'dp-mark-dialog-sq'},
                {type: '虫情终端', value: [1], comp: 'dp-mark-dialog-insect'},
                {type: '孢子', value: [39], comp: 'dp-mark-dialog-bz'},
                {type: '摄像头', value: [40], comp: 'dp-mark-dialog-monitor', width: '70%'},
                {type: '性诱测报灯', value: [49, 61, 72], comp: 'dp-mark-dialog-xy'},
                {type: '小虫体', value: [64], comp: 'dp-mark-dialog-xct'},
            ];
            const t = Number(this.terminalType) || Number(this.param.terminalType) || Number(this.param.terminal_type)
            if (!t) return null;
            const {comp = null, width} = enums.find(item => item.value.includes(t)) || {};
            return {
                name: comp,
                width: width || '52%'
            }
        },

        // 当前终端的详情
        terminalInfoList() {
            let list = [
                {label: '设备序列号', value: '--', key: 'terminal_serial'},
                {label: '设备状态', value: '--', key: 'online'},
                {label: '所属项目', value: '--', key: 'project_name'},
                {label: '经纬度', value: '--', key: 'coordinates'}
            ];
            const {
                terminal_serial,
                terminalSerial = '',
                online,
                longitude = '',
                latitude = '',
                terminal_name,
                project_name
            } = this.param;
            list.forEach(item => {
                const {key} = item;
                switch (key) {
                    case 'terminal_serial' :
                        item.value = terminal_serial || terminalSerial || '--';
                        break;
                    case 'online' :
                        item.value = online == 1 ? '在线' : '离线';
                        break;
                    case 'coordinates' :
                        if (longitude && latitude) {
                            item.value = `${longitude},${latitude}`
                        }
                        break;
                    case 'project_name':
                        item.value = project_name || "--"
                        break;
                }
            })
            return list;
        },
    },
    watch: {
        visible: {
            handler(v) {
                if (v) {
                    this.dialogShow = v;
                }
            }
        },
        dialogShow: {
            handler(v) {
                this.$emit('update:visible', v)
            }
        }
    }
})


/**
 * 墒情相关弹框
 */
Vue.component('dp-mark-dialog-sq', {
    template: `
    <div class="dp-mark-dialog__type dp-mark-dialog-sq">
        <dp-dialog-section title="实时数据">
            <template #search>
                <el-radio-group class="dialog-radio-group" @change="sensorClassifyChange" v-model="sensorData.curClassify" size="mini">
                    <el-radio-button :label="item.value" v-for="item of sensorData.classify">{{item.label}}</el-radio-button>
                </el-radio-group>
            </template>
            <dp-swiper-self :list="sensorData.list" :option="option_swiper" v-if="sensorData.list.length">
                <div class="sensor-siper-item" slot-scope="{ item }">
                     <div class="sensor-siper-item__value">
                        <div class="sensor-value">{{sensorValue(item)}}</div>
                        <div class="sensor-unit" v-show="item.sensor_type_id != 180">{{item.sensor_unit}}</div>
                     </div>
                     <div class="sensor-siper-item__info">
                        <div class="sensor-name">{{item.device_name}}</div>
                     </div>
                </div>
            </dp-swiper-self>
            <dp-no-data v-else></dp-no-data>
            <div class="sensor-chart-container">
                <div class="search-bar">    
                    <el-radio-group class="dialog-radio-group"  v-model="chartData.curTime" size="mini" @change="timeTypeChange">
                        <el-radio-button :label="item" v-for="item of chartData.timeTypes"></el-radio-button>
                    </el-radio-group>
                    <div class="date-range">
                        <el-date-picker @change="getsensorData" popper-class="dialog-date-picker-popper"  :disabled="chartData.curTime!=='自选'" :clearable="false" style="width: 300px;" size="mini" v-model="chartData.dateRange" type="daterange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" value-format="yyyy-MM-dd" :picker-options="pickerOptions"></el-date-picker>
                    </div>
                </div>
                <div class="chart-wraper">
                     <tp-charts :option="chartOption" v-if="chartOption"></tp-charts>
                     <dp-no-data v-else></dp-no-data>
                </div>
           </div>
        </dp-dialog-section>
      
    </div>`,

    props: {
        terminal_serial: {type: String},   // 终端序列号
        terminalId: {type: String},
    },

    data() {
        return {
            sensorData: {
                source: [],
                list: [],
                classify: [
                    {label: '全部', value: 0},
                    {label: '温湿度', value: 1},
                    {label: '土壤温度', value: 2},
                    {label: '土壤水分', value: 3},
                    {label: '其他', value: 4},
                ],
                curClassify: 0,
            },
            chartData: {
                timeTypes: ['天', '周', '月', '年', '自选'],
                curTime: '天',
                dateRange: [moment().subtract(1, 'day').format('YYYY-MM-DD'), moment().format('YYYY-MM-DD')],
                list: [],
                data_rows: [],
                device_id_sensor_map: {},

            },
            pickerOptions: '',
        }
    },

    computed: {
        chartOption() {
            if (!this.chartData.data_rows.length) return null;
            const list = this.chartData.list;
            if (!list.length) return null;
            const option = {
                grid: {
                    top: '22%',
                    left: '3%',
                    right: '3%',
                    bottom: '2%',
                    containLabel: true
                },
                tooltip: {
                    trigger: 'axis',
                    appendToBody: true,
                    formatter: params => {
                        const {name} = params[0] || {};
                        // tooltip 做列显示
                        return `<p style="margin-bottom:0.1rem;">${name}</p>` +
                            `<div class="tooltip-col-2">` +
                            params.map(item => {
                                const {marker, seriesName, data} = item;
                                const {classify, unit = ''} = JSON.parse(seriesName);
                                return `
                                    <div class="tooltip-item">
                                         ${marker}
                                         <span class="series-name">${classify}:</span>
                                         <span class="data">${data}${unit}</span>
                                    </div>`;
                            }).join('');
                        +`</div>`;
                    }
                },
                legend: {
                    data: list.map(item => item.classify),
                    textStyle: {
                        color: '#bbe1f9',
                        fontSize: 10
                    },
                    itemGap: 10,
                    type: 'scroll',
                    pageTextStyle: {
                        color: '#bbe1f9',
                    },
                    pageIconColor: '#006bff',
                    pageIconInactiveColor: '#a9a9a9',

                },
                xAxis: [
                    {
                        data: list[0].data.map(item => item.name),
                        splitLine: {
                            show: false,
                        },
                        axisLine: {
                            lineStyle: {
                                color: '#596f9a'
                            }
                        },
                        axisLabel: {
                            show: true,
                            textStyle: {
                                color: "#bbe1f9"
                            },
                            fontSize: 11,
                        },
                        axisTick: {
                            show: false,
                        },
                    },
                ],
                yAxis: [
                    {
                        type: 'value',
                        name: '',
                        nameTextStyle: {
                            color: "#bbe1f9",
                            fontSize: 11,
                            padding: [0, 30, -8, 0],
                        },
                        axisLabel: {
                            show: true,
                            textStyle: {
                                color: "#bbe1f9"
                            },
                            formatter: '{value}',
                            fontSize: 11,
                        },
                        splitLine: {
                            show: true,
                            lineStyle: {
                                type: 'dashed',
                                color: 'rgba(255, 255, 255, 0.1)'
                            }
                        },
                    }
                ],
                series: list.map((item, i) => {
                    return {
                        name: `${JSON.stringify(item)}`,
                        color: COLOR[i],
                        type: 'line',
                        smooth: true,
                        symbolSize: 3,
                        data: item.data.map(item => item.value),
                    }
                })
            };
            return option;
        },

        option_swiper() {
            return {
                slidesPerView: 5,
            }
        },
    },

    watch: {
        terminal_serial: {
            handler(num) {
                if (num) {
                    this.getSensorLastValue()
                    this.getsensorData();
                }
            },
            immediate: true
        }
    },

    methods: {
        /**
         * 土壤传感器分类单选切换
         */
        sensorClassifyChange(value) {
            if (value == 0) {
                this.sensorData.list = this.sensorData.source
            } else if (value == 1) {
                this.sensorData.list = this.sensorData.source.filter(item => item.device_name.indexOf("温度") != -1 || item.device_name.indexOf("湿度") != -1);
            } else if (value == 2) {
                this.sensorData.list = this.sensorData.source.filter(item => item.device_name.indexOf("土壤温度") != -1);
            } else if (value == 3) {
                this.sensorData.list = this.sensorData.source.filter(item => item.device_name.indexOf("土壤水分") != -1);
            } else if (value == 4) {
                this.sensorData.list = this.sensorData.source.filter(item => item.device_name.indexOf("土壤水分") == -1 && item.device_name.indexOf("土壤温度") == -1 && item.device_name.indexOf("温度") == -1 && item.device_name.indexOf("湿度") == -1);
            }
        },

        /**
         * 时间类型的切换
         */
        timeTypeChange(value) {
            switch (value) {
                case '天' :
                    this.chartData.dateRange = [moment().subtract(1, 'day').format('YYYY-MM-DD'), moment().format('YYYY-MM-DD')];
                    break;
                case '周' :
                    this.chartData.dateRange = [moment().subtract(7, 'day').format('YYYY-MM-DD'), moment().format('YYYY-MM-DD')];
                    break;
                case '月' :
                    this.chartData.dateRange = [moment().subtract(1, 'month').format('YYYY-MM-DD'), moment().format('YYYY-MM-DD')];
                    break;
                case '年' :
                    this.chartData.dateRange = [moment().subtract(1, 'year').format('YYYY-MM-DD'), moment().format('YYYY-MM-DD')];
                    break;
                case '自选' :
                    break;
            }
            this.getsensorData();
        },

        /**
         * 获取传感器列表
         */
        async getSensorLastValue() {
            const data = await tpUtils.request('action=com.top.hsf.field.monitor.sensor.lastValueList', {
                serialNums: this.terminal_serial
            });
            this.sensorData.list = data;
            this.sensorData.source = data;

            console.log(this.sensorData.list)
        },


        /**
         * 获取传感器历史数据
         */
        async getsensorData() {
            const [startDate, endDate] = this.chartData.dateRange || ['', ''];
            const data = await tpUtils.request('action=com.top.hsf.field.monitor.sensor.curvDataList', {
                serialNum: this.terminal_serial,
                period: 30,
                landUpLow: false,
                startDate: startDate,
                endDate: endDate,
            });
            const {data_rows, device_id_sensor_map, warning_list, alert_list} = data || {};
            this.chartData.data_rows = data_rows || [];
            this.chartData.device_id_sensor_map = device_id_sensor_map || [];
            this.chartData.warning_list = warning_list || [];
            this.chartData.alert_list = alert_list || [];

            const exclude = [140, 180, 184, 186];
            this.chartData.list = Object.entries(device_id_sensor_map).map(([key, value]) => {
                return {
                    sensor_type_id: value.sensorTypeId,
                    unit: value.unit,
                    classify: value.deviceName,
                    data: data_rows.map(ele => {
                        return {
                            name: moment(ele.datetime).format('YYYY-MM-DD HH:mm'),
                            value: ele.sensorData[key] || '-',
                        }
                    })
                }
            }).filter(item => !exclude.includes(item.sensor_type_id));
        },
    }
})

/**
 * 智能虫情测报灯相关弹框
 */
Vue.component('dp-mark-dialog-insect', {
    template: `
    <div class="dp-mark-dialog__type dp-mark-dialog-insect">
        <dp-dialog-section title="实时数据" >
            <template #search>
                <el-date-picker  @change="dateRangeChange" :clearable="false" style="width: 300px;" size="mini" v-model="searchData.dateRange" type="daterange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" value-format="yyyy-MM-dd" :picker-options="pickerOptions"></el-date-picker>
            </template>
            <div class="chart-wraper" style="height:30vh">
                <tp-charts :option="chartOption" v-if="chartOption"></tp-charts>
                <dp-no-data v-else height="30vh"></dp-no-data>
            </div>
        </dp-dialog-section>
       
        <dp-dialog-section title="图像列表" height="15vmin">
            <dp-swiper-self :list="swiperData.list" v-if="swiperData.list.length">
                <div class="insect-siper-item" slot-scope="{ item }">
                     <div class="insect-swiper-item__pic">
                        <el-image style="width: 100%; height: 100%;" :src="item.img_url" fit="fill" :preview-src-list="[item.orignal_url]"></el-image>
                        <div class="create-time">{{item.create_time}}</div>
                     </div>
                     <div class="insect-swiper-item__info">
                        <span class="info-num">虫子{{item.num}}头</span>
                        <span class="info-more" @click="openDetails(item)">详情>></span>
<!--                        <span class="info-more" @click="openDetails(item)" v-show="item.num>0">详情>></span>-->
                     </div>
                </div>
            </dp-swiper-self>
            <dp-no-data v-else></dp-no-data>
            <el-dialog title="详情" class="dp-mark-dialog__wrapper" custom-class="dp-mark-dialog"  :visible.sync="detailsData.visible" width="52%" append-to-body>
                 <div class="konva-container" style="height:760px;" v-loading="detailsData.loading"></div>
                 <div class="legend-list-konvas">    
                     <div class="li-item" v-for="item of detailsData.legendList">
                        <div class="dot" :style="{background:item.bgColor}"></div>
                        <span>{{item.insect_name}}</span> <span>{{item.number}}头</span>
                     </div>
                </div>
            </el-dialog>
        </dp-dialog-section> 
    </div>`,

    props: {
        terminal_serial: {type: String},   // 终端序列号
    },

    data() {
        return {
            searchData: {
                dateRange: [moment().subtract(7, 'day').format('YYYY-MM-DD'), moment().format('YYYY-MM-DD')]
            },
            pickerOptions: '',
            chartData: {
                list: [],
            },
            swiperData: {
                list: [],
                total: 0,
                page: 1,
                size: 20,
            },

            detailsData: {
                stage: null,
                layer: null,
                group: null,
                scale: 1,
                visible: false,
                legendList: [],
                loading: false
            },

        }
    },

    computed: {
        chartOption() {
            if (!this.chartData.list.length) return null;
            const option = {
                grid: {
                    top: '22%',
                    left: '3%',
                    right: '3%',
                    bottom: '2%',
                    containLabel: true
                },
                tooltip: {
                    trigger: 'axis',
                    appendToBody: true,
                    formatter: params => {
                        const {name} = params[0] || {};
                        // tooltip 做列显示
                        return `<p style="margin-bottom:0.1rem;">${name}</p>` +
                            `<div class="tooltip-col-2">` +
                            params.map(item => {
                                const {marker, seriesName, data} = item;
                                return `
                                    <div class="tooltip-item">
                                         ${marker}
                                         <span class="series-name">${seriesName}:</span>
                                         <span class="data">${data}</span>
                                    </div>`;
                            }).join('');
                        +`</div>`;
                    }
                },
                legend: {
                    data: this.chartData.list.map(item => item.classify),
                    textStyle: {
                        color: '#bbe1f9',
                        fontSize: 10
                    },
                    itemGap: 10,
                    type: 'scroll',
                    pageTextStyle: {
                        color: '#bbe1f9',
                    },
                    pageIconColor: '#006bff',
                    pageIconInactiveColor: '#a9a9a9',

                },
                xAxis: [
                    {
                        data: this.chartData.list[0].data.map(item => item.name),
                        splitLine: {
                            show: false,
                        },
                        axisLine: {
                            lineStyle: {
                                color: '#596f9a'
                            }
                        },
                        axisLabel: {
                            show: true,
                            textStyle: {
                                color: "#bbe1f9"
                            },
                            fontSize: 11,
                        },
                        axisTick: {
                            show: false,
                        },
                    },
                ],
                yAxis: [
                    {
                        type: 'value',
                        name: '只',
                        nameTextStyle: {
                            color: "#bbe1f9",
                            fontSize: 11,
                            padding: [0, 30, -8, 0],
                        },
                        axisLabel: {
                            show: true,
                            textStyle: {
                                color: "#bbe1f9"
                            },
                            formatter: '{value}',
                            fontSize: 11,
                        },
                        splitLine: {
                            show: true,
                            lineStyle: {
                                type: 'dashed',
                                color: 'rgba(255, 255, 255, 0.1)'
                            }
                        },
                    }
                ],
                series: this.chartData.list.map((item, i) => {
                    return {
                        name: item.classify,
                        color: COLOR[i],
                        type: 'line',
                        smooth: true,
                        symbolSize: 3,
                        data: item.data.map(item => item.value),
                    }
                })
            };
            return option;
        },


        option_swiper() {
            return {
                slidesPerGroup: 1,      // 滚动分组
                // speed: 1200
            }
        },
    },

    watch: {
        terminal_serial: {
            handler(num) {
                if (num) {
                    this.getCqCurvData()
                    this.getCqImgList();
                }
            },
            immediate: true
        }
    },

    methods: {
        /**
         * 点击打开详情
         * @param item
         */
        openDetails(item) {
            this.detailsData.visible = true;
            this.$nextTick(() => {
                this.initKonva(item);
            })
        },

        // 初始化konva
        async initKonva(item) {
            let dom = 'konva-container';
            const konva_width = document.querySelector(`.${dom}`).offsetWidth;
            const konva_height = document.querySelector(`.${dom}`).offsetHeight;
            this.detailsData.stage = new Konva.Stage({container: `.${dom}`, width: konva_width, height: konva_height});
            this.detailsData.layer = new Konva.Layer();
            this.detailsData.stage.add(this.detailsData.layer);
            this.detailsData.loading = true;
            const {width, height, img} = await loadImage(item.orignal_url);
            this.detailsData.loading = false;
            const ratio = width / height;
            const scale = konva_width / width;
            this.detailsData.scale = scale;
            const imgNode_width = konva_width; //宽度固定写死，宽度更具计算得到
            const imgNode_height = imgNode_width / ratio;

            // 创建组
            const group = new Konva.Group({
                draggable: false,
                name: 'group',
                x: (konva_width - imgNode_width) / 2,   // 默认居中位置
                y: (konva_height - imgNode_height) / 2,   // 默认居中位置,
                width: width,
                height: height,
                scaleX: scale,
                scaleY: scale,
            });

            // 创建图片元素
            const imgNode = new Konva.Image({
                draggable: false,
                x: 0,
                y: 0,
                id: 'imgNode',
                width: width,
                height: height,
                image: img,
            })
            group.add(imgNode);
            this.detailsData.group = group;
            this.detailsData.layer.add(group);
            this.detailsData.layer.draw();
            this.getinsectMark(item.img_id)
        },

        // 添加虫子标记层
        addMaskLayer(list) {
            list.forEach((item, index) => {
                const {position = [], count, type, bgColor} = item || {};
                console.log(bgColor)
                if (position && position.length > 0) {
                    position.forEach((ele, i) => {
                        const {rb, lt} = ele;
                        const [x1, y1] = lt.split(',');
                        const [x2, y2] = rb.split(',');
                        const width = x2 - x1;
                        const height = y2 - y1;
                        const poly = new Konva.Rect({
                            x: x1,
                            y: y1,
                            width: width,
                            height: height,
                            fill: bgColor + '20',
                            stroke: bgColor,
                            strokeWidth: 2,
                            strokeScaleEnabled: false,
                            dashEnabled: true,
                            dash: [5, 5]
                        });

                        const text = new Konva.Text({
                            x: x1,
                            y: y1,
                            width: width,
                            height: height,
                            text: i + 1,
                            fontSize: 15 / this.detailsData.scale,
                            fill: '#fff',
                            align: 'center',
                            verticalAlign: 'middle',
                        });

                        this.detailsData.group.add(poly);
                        this.detailsData.group.add(text);
                        this.detailsData.layer.add(this.detailsData.group);
                        this.detailsData.layer.draw();
                    })
                }
            })
        },

        // 获取虫子标记数据
        async getinsectMark(imgId) {
            const data = await tpUtils.request('action=com.top.hsf.field.monitor.insect.loadImgDetail', {
                imgId: imgId,
                insectIds: '',
            });

            const {cnts = []} = data || {};
            const list = cnts.map(item => {
                return {
                    bgColor: item.type_obj.color,
                    insect_name: item.type_obj.insect_name,
                    position: item.square ? JSON.parse(item.square) : [],
                    number: item.number
                }
            })
            this.detailsData.legendList = list;
            this.addMaskLayer(list);
        },

        dateRangeChange() {
            this.chartData.list = [];
            this.swiperData.list = [];
            this.getCqCurvData();
            this.getCqImgList();
        },

        /**
         * 获取虫害的相关图表数据
         */
        async getCqCurvData() {
            const [startDate, endDate] = this.searchData.dateRange || ['', ''];
            const data = await tpUtils.request('action=com.top.hsf.field.monitor.insect.curvBySerials', {
                serialNums: this.terminal_serial,
                insectType: '',
                subStatType: 2,
                statType: 1,
                statType: 5,
                startDate: startDate,
                endDate: endDate
            });

            if (data && data.length) {
                this.chartData.list = data.map(item => {
                    return {
                        classify: item.name,
                        data: item.data.map(ele => {
                            return {
                                name: moment(ele.x).format('YYYY-MM-DD'),
                                value: ele.y,
                            }
                        })
                    }
                })
            }
        },


        /**
         * 获取虫害的图片数据
         */
        async getCqImgList() {
            const [startDate, endDate] = this.searchData.dateRange || ['', ''];
            const data = await tpUtils.request('action=com.top.hsf.field.monitor.insect.pageImgsList', {
                serialNum: this.terminal_serial,
                startDate: startDate,
                endDate: endDate,
                insectTypes: "",
                page: 1,
                size: 100,
                desc: 1,
                ossUrl: "",
                urlSuffix: ""
            });

            let {total, list} = data || {};
            if (list && list.length) {
                list.forEach(item => {
                    if (item.insect_info && item.insect_info.length) {
                        item.num = item.insect_info.reduce((sum, item) => sum + item.number, 0)
                    } else {
                        item.num = 0;
                    }
                })
                this.swiperData.list = list;
            }
        },
    }
})

/**
 * 小虫体智能设备相关弹框
 */
Vue.component('dp-mark-dialog-xct', {
    template: `
    <div class="dp-mark-dialog__type dp-mark-dialog-insect">
        <dp-dialog-section title="实时数据" >
            <template #search>
                <el-date-picker  @change="dateRangeChange" :clearable="false" style="width: 300px;" size="mini" v-model="searchData.dateRange" type="daterange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" value-format="yyyy-MM-dd" :picker-options="pickerOptions"></el-date-picker>
            </template>
            <div class="chart-wraper" style="height:30vh">
                <tp-charts :option="chartOption" v-if="chartOption"></tp-charts>
                <dp-no-data v-else height="30vh"></dp-no-data>
            </div>
        </dp-dialog-section>
       
        <dp-dialog-section title="图像列表" height="15vmin">
            <dp-swiper-self :list="swiperData.list" v-if="swiperData.list.length">
                <div class="insect-siper-item" slot-scope="{ item }">
                     <div class="insect-swiper-item__pic">
                        <el-image style="width: 100%; height: 100%;" :src="item.img_url" fit="fill" :preview-src-list="[item.orignal_url]"></el-image>
                        <div class="create-time">{{item.create_time}}</div>
                     </div>
                     <div class="insect-swiper-item__info">
                        <span class="info-num">虫子{{item.num}}头</span>
                        <span class="info-more" @click="openDetails(item)" v-show="item.num>0">详情>></span>
                     </div>
                </div>
            </dp-swiper-self>
            <dp-no-data v-else></dp-no-data>
            <el-dialog title="详情" class="dp-mark-dialog__wrapper" custom-class="dp-mark-dialog"  :visible.sync="detailsData.visible" width="52%" append-to-body>
                 <div class="konva-container" style="height:760px;" v-loading="detailsData.loading"></div>
                 <div class="legend-list-konvas">    
                     <div class="li-item" v-for="item of detailsData.legendList">
                        <div class="dot" :style="{background:item.bgColor}"></div>
                        <span>{{item.insect_name}}</span> <span>{{item.number}}头</span>
                     </div>
                </div>
            </el-dialog>
        </dp-dialog-section> 
    </div>`,

    props: {
        terminal_serial: {type: String},   // 终端序列号
    },

    data() {
        return {
            searchData: {
                dateRange: [moment().subtract(7, 'day').format('YYYY-MM-DD'), moment().format('YYYY-MM-DD')]
            },
            pickerOptions: '',
            chartData: {
                list: [],
            },
            swiperData: {
                list: [],
                total: 0,
                page: 1,
                size: 20,
            },

            detailsData: {
                stage: null,
                layer: null,
                group: null,
                scale: 1,
                visible: false,
                legendList: [],
                loading: false
            },

        }
    },

    computed: {
        chartOption() {
            if (!this.chartData.list.length) return null;
            const option = {
                grid: {
                    top: '22%',
                    left: '3%',
                    right: '3%',
                    bottom: '2%',
                    containLabel: true
                },
                tooltip: {
                    trigger: 'axis',
                    appendToBody: true,
                    formatter: params => {
                        const {name} = params[0] || {};
                        // tooltip 做列显示
                        return `<p style="margin-bottom:0.1rem;">${name}</p>` +
                            `<div class="tooltip-col-2">` +
                            params.map(item => {
                                const {marker, seriesName, data} = item;
                                return `
                                    <div class="tooltip-item">
                                         ${marker}
                                         <span class="series-name">${seriesName}:</span>
                                         <span class="data">${data}</span>
                                    </div>`;
                            }).join('');
                        +`</div>`;
                    }
                },
                legend: {
                    data: this.chartData.list.map(item => item.classify),
                    textStyle: {
                        color: '#bbe1f9',
                        fontSize: 10
                    },
                    itemGap: 10,
                    type: 'scroll',
                    pageTextStyle: {
                        color: '#bbe1f9',
                    },
                    pageIconColor: '#006bff',
                    pageIconInactiveColor: '#a9a9a9',

                },
                xAxis: [
                    {
                        data: this.chartData.list[0].data.map(item => item.name),
                        splitLine: {
                            show: false,
                        },
                        axisLine: {
                            lineStyle: {
                                color: '#596f9a'
                            }
                        },
                        axisLabel: {
                            show: true,
                            textStyle: {
                                color: "#bbe1f9"
                            },
                            fontSize: 11,
                        },
                        axisTick: {
                            show: false,
                        },
                    },
                ],
                yAxis: [
                    {
                        type: 'value',
                        name: '只',
                        nameTextStyle: {
                            color: "#bbe1f9",
                            fontSize: 11,
                            padding: [0, 30, -8, 0],
                        },
                        axisLabel: {
                            show: true,
                            textStyle: {
                                color: "#bbe1f9"
                            },
                            formatter: '{value}',
                            fontSize: 11,
                        },
                        splitLine: {
                            show: true,
                            lineStyle: {
                                type: 'dashed',
                                color: 'rgba(255, 255, 255, 0.1)'
                            }
                        },
                    }
                ],
                series: this.chartData.list.map((item, i) => {
                    return {
                        name: item.classify,
                        color: COLOR[i],
                        type: 'line',
                        smooth: true,
                        symbolSize: 3,
                        data: item.data.map(item => item.value),
                    }
                })
            };
            return option;
        },


        option_swiper() {
            return {
                slidesPerGroup: 1,      // 滚动分组
                // speed: 1200
            }
        },
    },

    watch: {
        terminal_serial: {
            handler(num) {
                if (num) {
                    this.getCqCurvData()
                    this.getCqImgList();
                }
            },
            immediate: true
        }
    },

    methods: {
        /**
         * 点击打开详情
         * @param item
         */
        openDetails(item) {
            this.detailsData.visible = true;
            this.$nextTick(() => {
                this.initKonva(item);
            })
        },

        // 初始化konva
        async initKonva(item) {
            let dom = 'konva-container';
            const konva_width = document.querySelector(`.${dom}`).offsetWidth;
            const konva_height = document.querySelector(`.${dom}`).offsetHeight;
            this.detailsData.stage = new Konva.Stage({container: `.${dom}`, width: konva_width, height: konva_height});
            this.detailsData.layer = new Konva.Layer();
            this.detailsData.stage.add(this.detailsData.layer);
            this.detailsData.loading = true;
            const {width, height, img} = await loadImage(item.orignal_url);
            this.detailsData.loading = false;
            const ratio = width / height;
            const scale = konva_width / width;
            this.detailsData.scale = scale;
            const imgNode_width = konva_width; //宽度固定写死，宽度更具计算得到
            const imgNode_height = imgNode_width / ratio;

            // 创建组
            const group = new Konva.Group({
                draggable: false,
                name: 'group',
                x: (konva_width - imgNode_width) / 2,   // 默认居中位置
                y: (konva_height - imgNode_height) / 2,   // 默认居中位置,
                width: width,
                height: height,
                scaleX: scale,
                scaleY: scale,
            });

            // 创建图片元素
            const imgNode = new Konva.Image({
                draggable: false,
                x: 0,
                y: 0,
                id: 'imgNode',
                width: width,
                height: height,
                image: img,
            })
            group.add(imgNode);
            this.detailsData.group = group;
            this.detailsData.layer.add(group);
            this.detailsData.layer.draw();
            this.getinsectMark(item.img_id)
        },

        // 添加虫子标记层
        addMaskLayer(list) {
            list.forEach((item, index) => {
                const {position = [], count, type, bgColor} = item || {};
                console.log(bgColor)
                if (position && position.length > 0) {
                    position.forEach((ele, i) => {
                        const {rb, lt} = ele;
                        const [x1, y1] = lt.split(',');
                        const [x2, y2] = rb.split(',');
                        const width = x2 - x1;
                        const height = y2 - y1;
                        const poly = new Konva.Rect({
                            x: x1,
                            y: y1,
                            width: width,
                            height: height,
                            fill: bgColor + '20',
                            stroke: bgColor,
                            strokeWidth: 2,
                            strokeScaleEnabled: false,
                            dashEnabled: true,
                            dash: [5, 5]
                        });

                        const text = new Konva.Text({
                            x: x1,
                            y: y1,
                            width: width,
                            height: height,
                            text: i + 1,
                            fontSize: 15 / this.detailsData.scale,
                            fill: '#fff',
                            align: 'center',
                            verticalAlign: 'middle',
                        });

                        this.detailsData.group.add(poly);
                        this.detailsData.group.add(text);
                        this.detailsData.layer.add(this.detailsData.group);
                        this.detailsData.layer.draw();
                    })
                }
            })
        },

        // 获取虫子标记数据
        async getinsectMark(imgId) {
            const data = await requestApi('getCqImageDetail', {
                serialNums: this.terminal_serial,
                imgId: imgId,
            });
            const {cnts = []} = data || {};
            const list = cnts.map(item => {
                return {
                    bgColor: item.type_obj.color,
                    insect_name: item.type_obj.insect_name,
                    position: item.square ? JSON.parse(item.square) : [],
                    number: item.number
                }
            })
            this.detailsData.legendList = list;
            this.addMaskLayer(list);
        },

        dateRangeChange() {
            this.chartData.list = [];
            this.swiperData.list = [];
            this.getCqCurvData();
            this.getCqImgList();
        },

        /**
         * 获取虫害的相关图表数据
         */
        async getCqCurvData() {
            const [startDate, endDate] = this.searchData.dateRange || ['', ''];
            const data = await tpUtils.request('action=com.top.hsf.field.monitor.dfs.curvBySerials', {
                serialNum: this.terminal_serial,
                startDate: startDate,
                endDate: endDate
            });
            const {daily_insects, insects} = data || {};

            if (daily_insects && insects && daily_insects.length && insects.length) {
                this.chartData.list = insects.map(item => {
                    return {
                        classify: item.insectName,
                        color: item.color,
                        data: daily_insects.map(ele => {
                            const temp = ele.insectCounts.find(e => e.insectId === item.insectId) || {};
                            return {
                                name: moment(ele.date).format('YYYY-MM-DD'),
                                value: temp.value || 0,
                            }
                        })
                    }
                })
            }

            // if (data && data.length) {
            //     this.chartData.list = data.map(item => {
            //         return {
            //             classify: item.name,
            //             data: item.data.map(ele => {
            //                 return {
            //                     name: moment(ele.x).format('YYYY-MM-DD'),
            //                     value: ele.y,
            //                 }
            //             })
            //         }
            //     })
            // }

        },


        /**
         * 获取虫害的图片数据
         */
        async getCqImgList() {
            const [startDate, endDate] = this.searchData.dateRange || ['', ''];
            const data = await tpUtils.request('action=com.top.hsf.field.monitor.dfs.pageImgsList', {
                serialNum: this.terminal_serial,
                startDate: startDate + ' 00:00:00',
                endDate: endDate + ' 00:00:00',
                insectTypes: "",
                page: 1,
                size: 100,
                timeOrder: "",
            });

            let {total, list} = data || {};
            if (list && list.length) {
                list.forEach(item => {
                    if (item.insect_info && item.insect_info.length) {
                        item.num = item.insect_info.reduce((sum, item) => sum + item.number, 0)
                    } else {
                        item.num = 0;
                    }
                })
                this.swiperData.list = list;
            }
        },
    }
})

/**
 * 性诱测报灯相关弹框
 */
Vue.component('dp-mark-dialog-xy', {
    template: `
    <div class="dp-mark-dialog__type dp-mark-dialog-xy">
        <dp-dialog-section title="数据分析" >
            <div class="search-bar">    
                <el-radio-group class="dialog-radio-group"  v-model="chartData.curTime" size="mini" @change="timeTypeChange">
                    <el-radio-button :label="item" v-for="item of chartData.timeTypes"></el-radio-button>
                </el-radio-group>
                <div class="date-range">
                    <el-date-picker @change="dateRangeChange" popper-class="dialog-date-picker-popper"  :disabled="chartData.curTime!=='自选'" :clearable="false" style="width: 300px;" size="mini" v-model="chartData.dateRange" type="daterange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" value-format="yyyy-MM-dd" :picker-options="pickerOptions"></el-date-picker>
                </div>
            </div>
            <div class="chart-wraper" style="height:35vh">
                <tp-charts :option="chartOption" v-if="chartOption"></tp-charts>
                <dp-no-data v-else height="30vh"></dp-no-data>
            </div>
        </dp-dialog-section>
    </div>`,

    props: {
        terminal_serial: {type: String},   // 终端序列号
    },

    data() {
        return {
            pickerOptions: '',
            chartData: {
                timeTypes: ['周', '月', '年', '自选'],
                curTime: '周',
                dateRange: [moment().subtract(7, 'day').format('YYYY-MM-DD'), moment().format('YYYY-MM-DD')],
                list: [],
            },
        }
    },

    computed: {
        chartOption() {
            if (!this.chartData.list.length) return null;
            const option = {
                grid: {
                    top: '22%',
                    left: '3%',
                    right: '3%',
                    bottom: '2%',
                    containLabel: true
                },
                tooltip: {
                    trigger: 'axis',
                },
                xAxis: [
                    {
                        data: this.chartData.list.map(item => item.name),
                        splitLine: {
                            show: false,
                        },
                        axisLine: {
                            lineStyle: {
                                color: '#596f9a'
                            }
                        },
                        axisLabel: {
                            show: true,
                            textStyle: {
                                color: "#bbe1f9"
                            },
                            fontSize: 11,
                        },
                        axisTick: {
                            show: false,
                        },
                    },
                ],
                yAxis: [
                    {
                        type: 'value',
                        name: '只',
                        nameTextStyle: {
                            color: "#bbe1f9",
                            fontSize: 11,
                            padding: [0, 30, -8, 0],
                        },
                        axisLabel: {
                            show: true,
                            textStyle: {
                                color: "#bbe1f9"
                            },
                            formatter: '{value}',
                            fontSize: 11,
                        },
                        splitLine: {
                            show: true,
                            lineStyle: {
                                type: 'dashed',
                                color: 'rgba(255, 255, 255, 0.1)'
                            }
                        },
                    }
                ],
                series: {
                    name: '诱虫数量',
                    type: 'line',
                    smooth: true,
                    symbolSize: 3,
                    data: this.chartData.list.map(item => item.value),
                }
            };
            return option;
        },
    },

    watch: {
        terminal_serial: {
            handler(num) {
                if (num) {
                    this.getCqCurvData()
                }
            },
            immediate: true
        }
    },

    methods: {
        /**
         * 时间类型的切换
         */
        timeTypeChange(value) {
            switch (value) {
                case '周' :
                    this.chartData.dateRange = [moment().subtract(7, 'day').format('YYYY-MM-DD'), moment().format('YYYY-MM-DD')];
                    break;
                case '月' :
                    this.chartData.dateRange = [moment().subtract(1, 'month').format('YYYY-MM-DD'), moment().format('YYYY-MM-DD')];
                    break;
                case '年' :
                    this.chartData.dateRange = [moment().subtract(1, 'year').format('YYYY-MM-DD'), moment().format('YYYY-MM-DD')];
                    break;
                case '自选' :
                    break;
            }
            this.chartData.list = [];
            this.getCqCurvData();
        },

        dateRangeChange() {
            this.chartData.list = [];
            this.getCqCurvData();
        },

        /**
         * 获取虫害的相关图表数据
         */
        async getCqCurvData() {
            const [startDate, endDate] = this.chartData.dateRange || ['', ''];
            const data = await tpUtils.request('action=com.top.hsf.field.monitor.xy.curvBySerials', {
                serialNum: this.terminal_serial,
                decoyType: '',
                startDate: startDate,
                endDate: endDate
            });

            if (data && data.length) {
                this.chartData.list = data.map(item => {
                    return {
                        name: item.img_time,
                        value: item.add_num
                    }
                })
            }
        },
    }
})

/**
 * 孢子相关弹框
 */
Vue.component('dp-mark-dialog-bz', {
    template: `
    <div class="dp-mark-dialog__type dp-mark-dialog-bz">
        <dp-dialog-section title="图像列表" >
            <template #search>
                <el-date-picker  @change="dateRangeChange" :clearable="false" style="width: 300px;" size="mini" v-model="searchData.dateRange" type="daterange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" value-format="yyyy-MM-dd" :picker-options="pickerOptions"></el-date-picker>
            </template>

           <div class="pic-list-wrapper">
                <div class="pic-list" v-if="list.length">
                    <div class="li-item" v-for="item of list">
                          <img :src="item.thumb_url" alt="">
                          <div class="time">
                            {{item.capture_time}}
                          </div>
                    </div>
                </div>
                
                <dp-no-data v-else height="30vh"></dp-no-data>
           </div>
           
           <el-pagination
              style="margin-top:0.2rem;"
              background
              @current-change="handleCurrentChange"
              :current-page.sync="page"
              :page-size="size"
              layout="prev, pager, next, jumper"
              :total="total">
            </el-pagination>
                

        </dp-dialog-section>
    </div>`,
    props: {
        terminal_serial: {type: String},   // 终端序列号
    },
    data() {
        return {
            searchData: {
                dateRange: [moment().subtract(7, 'day').format('YYYY-MM-DD'), moment().format('YYYY-MM-DD')]
            },
            pickerOptions: '',
            list: [],
            page: 1,
            size: 1,
            total: 0,
        }
    },
    computed: {
        option_chart() {
            if (!this.chartData.list.length) return null;
            const xAxisData = this.chartData.list[0].data.map(item => moment(item.x).format('YYYY-MM-DD'));
            let legendData = [];
            let series = [];

            this.chartData.list.forEach(item => {
                series.push({
                    name: item.name,
                    data: item.data.map(ele => ele.y.toFixed(0)),
                })
                legendData.push(item.name)
            })

            return {
                grid: {bottom: 38},
                yAxis: {
                    minInterval: 1,
                },
                xAxisData,
                series: series,
                legend: {
                    data: legendData,
                    bottom: 0,
                    left: 'center',
                },

                /*todo 考虑下很多项的情况*/
                tooltip: {
                    appendToBody: true,
                    formatter: (param) => {
                        html = `<div style="margin-bottom:6px;">${param[0].name}</div>`;
                        param.filter(item => item.value != 0).forEach((item, idx) => {
                            const unit = '头';
                            html += `${item.marker} <span style="line-height:2;">${item.seriesName}：${item.value}${unit || ""}</span> <br />`;
                        })
                        return html;
                    }
                }
            }
        },
        option_swiper() {
            return {
                slidesPerGroup: 1,      // 滚动分组
                // speed: 1200
            }
        },
    },
    watch: {
        terminal_serial: {
            handler(num) {
                if (num) {
                    this.getImgList()
                }
            },
            immediate: true
        }
    },
    methods: {

        /**
         * 日期范围发生变化
         */
        dateRangeChange() {
            this.chartData.list = [];
            this.swiperData.list = [];
            this.getImgList();
        },

        /**
         * 获取病害的图片数据
         */
        async getImgList() {
            this.list = [];
            const [startDate, endDate] = this.searchData.dateRange || ['', ''];
            const data = await tpUtils.request('action=com.top.hsf.field.monitor.spore.pageImgsBy', {
                serialNum: this.terminal_serial,
                startDate: startDate,
                endDate: endDate,
                sporeTypes: "",
                page: this.page,
                size: this.size,
            });

            let {total, list} = data || {};
            this.total = total;
            if (list && list.length) {
                this.list = list[0].imgs
            }
        },

        /**
         * 页码发生变化
         * @param page
         */
        handleCurrentChange(page) {
            this.page = page;
            this.getImgList();
        },
    }
})

/**
 * 监控相关弹框
 */
Vue.component('dp-mark-dialog-monitor', {
    template: `
    <div class="dp-mark-dialog__type dp-mark-dialog-monitor">
        <div class="monitor-content-left">
            <isc-video-player 
                ref="player"
                v-if="videoShow"
                :h5="h5Config"
                :camera-list="monitorList"
                :layout="layout"
                @select="videoLayoutSelect"
            ></isc-video-player>
            <div class="video-layout" v-show="videoShow">
                <i class="el-icon-crop"></i>
                <div class="video-layout-box">
                    <span v-for="(item,index) in layoutList" @click="videoLayoutClick(item)" :class="layoutActive == item.value?'active':''" :key="index + 'lay'">{{item.name}}</span>
                </div>
            </div>
            <div v-show="videoShow" @click="stopVideoClick" class="video-layout stop-video" title="关闭当前">
                <i class="el-icon-news"></i>
            </div>
        </div> 
        <div class="monitor-content-right">
            <h3 class="monitor-content-right-tit">监控列表</h3>
            <div class="monitor-list-content">
                <div class="monitor-list-box" v-for="(item,index) in monitorList"  @click="monitorListClick(item)">
                    <p>{{item.device_name || item.deviceName}}</p>
                    <span :class="getClass(item.state)"></span>
                </div>
            </div>
            <div class="ctrl-top-box">
                <div class="ctrl-top-box-left">
                    <p @mousedown="ptzCtrl('LEFT_UP',0)" @mouseup="ptzCtrl('LEFT_UP',1)" title="左上"><i class="el-icon-arrow-up"></i></p>
                    <p @mousedown="ptzCtrl('UP',0)" @mouseup="ptzCtrl('UP',1)" title="上"><i class="el-icon-arrow-up"></i></p>
                    <p @mousedown="ptzCtrl('RIGHT_UP',0)" @mouseup="ptzCtrl('RIGHT_UP',1)" title="右上"><i class="el-icon-arrow-up"></i></p>
                    <p @mousedown="ptzCtrl('LEFT',0)" @mouseup="ptzCtrl('LEFT',1)" title="左"><i class="el-icon-arrow-left"></i></p>
                    <p></p>
                    <p @mousedown="ptzCtrl('RIGHT',0)" @mouseup="ptzCtrl('RIGHT',1)" title="右"><i class="el-icon-arrow-right"></i></p>
                    <p @mousedown="ptzCtrl('LEFT_DOWN',0)" @mouseup="ptzCtrl('LEFT_DOWN',1)" title="左下"><i class="el-icon-arrow-down"></i></p>
                    <p @mousedown="ptzCtrl('DOWN',0)" @mouseup="ptzCtrl('DOWN',1)" title="下"><i class="el-icon-arrow-down"></i></p>
                    <p @mousedown="ptzCtrl('RIGHT_DOWN',0)" @mouseup="ptzCtrl('RIGHT_DOWN',1)" title="右下"><i class="el-icon-arrow-down"></i></p>
                </div>
                <div class="ctrl-top-box-right">
                    <p @mousedown="ptzCtrl('ZOOM_IN',0)" @mouseup="ptzCtrl('ZOOM_IN',1)" title="焦距前调"><i class="el-icon-circle-plus-outline"></i></p>
                    <p style="visibility: hidden;"></p>
                    <p @mousedown="ptzCtrl('ZOOM_OUT',0)" @mouseup="ptzCtrl('ZOOM_OUT',1)" title="焦距后调"><i class="el-icon-remove-outline"></i></p>
                    <p style="visibility: hidden;"></p>
                </div>
            </div>
            <div class="ctrl-title-box">
                <span>定点预设</span>
                <i @click="addPresetPoint" title="添加预设点" class="el-icon-circle-plus-outline"></i>
            </div>
            <div class="ctrl-bottom-box" v-show="presetPointList.length">
                <div class="ctrl-content-box" v-for="(item,index) in presetPointList" :key="index + 'pnt'">
                    <span>{{item.presetName}}</span>
                    <div>
                        <i @click="deletePresetPoint(item)" title="删除" class="el-icon-close"></i>
                        <i @click="setPresetPoint(item)" title="预置点" class="el-icon-aim"></i>
                    </div>
                </div>
            </div>
            <div class="ctrl-bottom-box" v-show="!presetPointList.length">
                <div class="no-data-t">暂无预置点</div>
            </div>
        </div>
    </div>`,
    props: {
        terminal_id: {type: String, default: ''},
    },
    data() {
        return {
            initialSlide: 0,
            videoList: [],
            device_num1: '', //视频播放的id
            // 视频布局
            layoutList: [
                {name: "1x1", value: 1},
                {name: "2x2", value: 4},
                {name: "3x3", value: 9},
                {name: "4x4", value: 16},
            ],
            layoutActive: 4,
            layout: "2x2",
            videoShow: true,
            h5Config: {
                urlFunc: this.queryPlayUrl,
            },
            // 监控设备列表
            monitorList: [],
            // 窗口选中code
            cameraIndexCode: "",
            // 预设点列表
            presetPointList: [],
            protocol: "ws",
        };
    },
    watch: {
        terminal_id: {
            handler(val) {
                if (val) {
                    this.getCameraInfoList();
                }
            },
            immediate: true
        }
    },
    methods: {
        // 获取状态类名
        getClass(state) {
            if (state == 1) {
                return "monitor-img-checked"
            } else if (state == 99) {
                return "monitor-img-loading"
            } else if (state == -1) {
                return "monitor-img-error"
            } else {
                return ""
            }
        },

        /**
         * 初始化视频
         */
        initVideo() {
            window.oWebControl && window.oWebControl.JS_StopRealPlayAll(true).then(() => {
            }, () => {
            });
            this.videoShow = false;
            this.$nextTick(() => {
                this.videoShow = true;
            })
        },

        queryPlayUrl(cameraIndexCode, protocol) {
            console.log('取流==>', cameraIndexCode, protocol)
            this.protocol = protocol;
            return new Promise(resolve => {
                let obj = this.monitorList.find(item => item.cameraIndexCode === cameraIndexCode);
                let params = {"deviceId": obj.deviceId, "protocol": protocol};
                tpHttp.post(this, "action=com.top.hsf.field.monitor.isc.previewUrl", {param: JSON.stringify(params)}, (data, code, message) => {
                    if (code == 0 && data) {
                        resolve(data);
                    }
                })
            });
        },

        /**
         * 播放窗口选中
         */
        videoLayoutSelect(code) {
            this.cameraIndexCode = code;
            this.getPresetPointList();
        },

        /**
         * 视频布局点击
         */
        videoLayoutClick(item) {
            this.initVideo();
            if (item) {
                this.layoutActive = item.value;
                this.layout = item.name;
            }
            let arr = this.monitorList.map(item => {
                return item.cameraIndexCode
            })

            if (this.isPlayback) {
                setTimeout(() => {
                    this.$refs.player.startBatchPreview(arr, true)
                        .catch(error => {
                            console.log(error.message)
                        });
                }, 300)
                return
            }
            setTimeout(() => {
                this.$refs.player.startBatchPreview(arr)
                    .catch(error => {
                        console.log(error.message)
                    });
            }, 300)
        },
        /**
         * 关闭当前窗口点击
         */
        stopVideoClick() {
            this.$refs.player.stopPreview(this.cameraIndexCode);
        },

        /**
         * 获取预置点列表
         */
        getPresetPointList() {
            let obj = this.monitorList.find(item => item.cameraIndexCode === this.cameraIndexCode);
            let params = {device_id: obj && obj.device_id, camera_index_code: this.cameraIndexCode};
            tpHttp.post(this, "action=com.top.hsf.field.monitor.isc.preset.list", {param: JSON.stringify(params)}, (data, code, message) => {
                if (code == 0 && data && data.length) {
                    this.presetPointList = data;
                } else {
                    this.presetPointList = [];
                }
            });
        },
        /**
         * 云台控制调用
         * action( 0开始 1关闭 )
         * command(LEFT 左转 RIGHT右转 UP 上转 DOWN 下转 ZOOM_IN 焦距变大 ZOOM_OUT 焦距变小 LEFT_UP 左上 LEFT_DOWN 左下 RIGHT_UP 右上 RIGHT_DOWN 右下 FOCUS_NEAR 焦点前移 FOCUS_FAR 焦点后移 IRIS_ENLARGE 光圈扩大 IRIS_REDUCE 光圈缩小 WIPER_SWITCH 接通雨刷开关 START_RECORD_TRACK 开始记录轨迹 STOP_RECORD_TRACK 停止记录轨迹 START_TRACK 开始轨迹 STOP_TRACK 停止轨迹 以下命令presetIndex不可 为空： GOTO_PRESET到预置点)
         * speed （0-100）
         */
        ptzCtrl(command, action) {
            let obj = this.monitorList.find(item => item.cameraIndexCode === this.cameraIndexCode);
            let params = {
                device_id: obj && obj.device_id,
                camera_index_code: this.cameraIndexCode,
                action: action,
                command: command,
                speed: 80
            };
            if (action == 1) {
                setTimeout(() => {
                    tpHttp.post(this, "action=com.top.hsf.field.monitor.isc.ptz.ctrl", {param: JSON.stringify(params)}, (data, code, message) => {
                        if (code == 0) {

                        } else {
                            this.$message({
                                message: message,
                                type: "error"
                            });
                        }
                    });
                }, 800)
                return
            }
            tpHttp.post(this, "action=com.top.hsf.field.monitor.isc.ptz.ctrl", {param: JSON.stringify(params)}, (data, code, message) => {
                if (code == 0) {

                } else {
                    this.$message({
                        message: message,
                        type: "error"
                    });
                }
            });
        },

        /**
         * 监控列表点击
         */
        monitorListClick(item) {
            this.videoCtrlBoxShow = false;
            this.$refs.player.startPreview(item.cameraIndexCode)
                .catch(error => {
                    console.log(error.message)
                });
        },

        /**
         * 添加预置点点击
         */
        addPresetPoint() {
            this.$prompt('请输入预置点名称', '提示', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                inputPattern: /^[\s\S]*.*[^\s][\s\S]*$/,
                inputErrorMessage: '预置点名称不能为空'
            }).then(({value}) => {
                let obj = this.monitorList.find(item => item.cameraIndexCode === this.cameraIndexCode);
                let params = {
                    device_id: obj && obj.device_id,
                    camera_index_code: this.cameraIndexCode,
                    preset_name: value,
                    bind_device_id: obj.device_id
                };
                tpHttp.post(this, "action=com.top.hsf.field.monitor.isc.preset.add", {param: JSON.stringify(params)}, (data, code, message) => {
                    if (code == 0) {
                        this.getPresetPointList();
                    } else {
                        this.$message({
                            type: 'error',
                            message: message
                        });
                    }
                });
            }).catch(() => {
            });
        },
        /**
         * 删除预置点点击
         */
        deletePresetPoint(item) {
            this.$confirm('此操作将删除该预置点, 是否继续?', '提示', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
            }).then(() => {
                let obj = this.monitorList.find(item => item.cameraIndexCode === this.cameraIndexCode);
                let params = {
                    device_id: obj && obj.device_id,
                    camera_index_code: item.cameraIndexCode,
                    preset_index: item.presetIndex
                };
                tpHttp.post(this, "action=com.top.hsf.field.monitor.isc.preset.del", {param: JSON.stringify(params)}, (data, code, message) => {
                    if (code == 0) {
                        this.getPresetPointList();
                    } else {
                        this.$message({
                            type: 'error',
                            message: message
                        });
                    }
                });
            }).catch(() => {
            });
        },
        /**
         * 设置预置点点击
         */
        setPresetPoint(item) {
            let obj = this.monitorList.find(item => item.cameraIndexCode === this.cameraIndexCode);
            let params = {
                device_id: obj && obj.device_id,
                camera_index_code: this.cameraIndexCode,
                preset_index: item.presetIndex
            };
            tpHttp.post(this, "action=com.top.hsf.field.monitor.isc.preset.goto", {param: JSON.stringify(params)}, (data, code, message) => {
                if (code == 0) {

                } else {
                    this.$message({
                        type: 'error',
                        message: message
                    });
                }
            })
        },
        close() {
            this.$emit('close', 'visible4');
        },

        /**
         * 获取监控列表
         */
        async getCameraInfoList() {
            const res = await tpUtils.request('action=com.top.hsf.field.monitor.isc.getCameraInfoList', {
                terminalIds: this.terminal_id
            })
            if (res && res.length) {
                this.monitorList = res.map(item => {
                    return {
                        ...item,
                        camera_index_code: item.device_num,
                        cameraIndexCode: item.device_num,
                        deviceId: item.device_id,
                        deviceTypeId: item.device_type_id
                    }
                })
                this.$nextTick(() => {
                    this.videoLayoutClick();
                })
            }
        },
    },
})

/**
 * 弹框中区域组件
 */
Vue.component('dp-dialog-section', {
    template: `
    <div class="dp-dialog-section">
        <div class="dialog-section__top">
            <div class="left">
                <div class="name">{{title}}</div>   
                <div class="search">
                    <slot name="search"></slot>
                </div>
            </div>
            <div class="right">
                <slot name="other"></slot>
            </div>
        </div>
         <div class="dialog-section__content" :style="content_style">
            <slot>
                <dp-no-data></dp-no-data>
            </slot>
         </div>
    </div>`,

    props: {
        title: {type: String, default: '标题'},
        height: {type: [String, Number], default: '25vmin'},
    },


    computed: {
        option_chart() {
            return null;
        },

        content_style() {
            return {
                // height: this.height
            }
        }
    }
})

/**
 * swiper封装
 */
Vue.component('dp-swiper-self', {
    template: `
        <div class="dp-swiper">
            <div class="swiper-btn-prev swiper-btn">
                <img src="../../resources/img/dp-mark-dialog/dialog-swiper-pre.png" alt="左按钮" v-show="showArrow">
            </div>
            <div class="swiper" :id="this.uuid">
                <div class="swiper-wrapper">
                    <div class="swiper-slide" v-for="(item, index) in list" :key="item.id || index">
                        <slot :item="item" :index="index"></slot>
                    </div>
                </div>
            </div>
            <div class="swiper-btn-next swiper-btn">
                <img src="../../resources/img/dp-mark-dialog/dialog-swiper-next.png" alt="右按钮" v-show="showArrow">
            </div>
        </div>
    `,
    props: {
        option: {type: Object, default: () => ({})},
        list: {type: Array, default: () => []}
    },
    data() {
        return {
            swiper: null,
            uuid: '',
        }
    },

    computed: {
        showArrow() {
            const slidesPerView = this.option.slidesPerView || 4;
            if (this.list.length > 0 && this.list.length > slidesPerView) {
                return true;
            }
            return false
        }
    },

    watch: {
        list: {
            handler(val) {
                this.$nextTick(() => {
                    this.swiper && this.swiper.update(true);
                })
            },
            deep: true
        },
    },
    methods: {
        initSwiper() {
            const option = {
                slidesPerView: 4,
                spaceBetween: 15,
                loop: false,
                navigation: {
                    nextEl: '.swiper-btn-next',
                    prevEl: '.swiper-btn-prev',
                },
                on: {
                    transitionStart: (swiper) => {
                        let index = swiper.activeIndex;
                        this.$emit("swiper-info", swiper);
                        this.$emit('swiper-index', index);
                    },
                    // 向前切换
                    slideNextTransitionStart: (swiper) => {
                        let index = swiper.activeIndex;
                        this.$emit('swiper-next', index, swiper);
                    },
                    // 拖动slide时执行
                    sliderMove: (swiper) => {
                        let index = swiper.activeIndex;
                        this.$emit('swiper-move', index, swiper);
                    },
                },
            }
            this.swiper = new Swiper(`#${this.uuid}`, {...option, ...this.option});
        },
    },
    created() {
        this.uuid = uuidGenerate('swiper_');
    },
    mounted() {
        this.$nextTick(() => {
            this.initSwiper();
        })
    },
});

/**
 * 生成唯一标识
 * @returns {string}
 */
function uuidGenerate(prefix) {
    let d = new Date().getTime();

    if (window.performance && typeof window.performance.now === "function") {
        d += performance.now(); //use high-precision timer if available
    }

    const uuid = 'xxxxxxxx'.replace(/[xy]/g, function (c) {
        const r = (d + Math.random() * 16) % 16 | 0;
        d = Math.floor(d / 16);
        return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
    });

    return prefix + uuid.substring(0, 8);
}


/**
 * 如果为整数返回整数，如果为小数，保留两位小数点
 * @param value
 * @returns {number|*}
 */
function formatNumber(value) {
    if (!value) return '- -';
    const theValue = Number(value);
    if (Number.isInteger(theValue)) {
        return theValue;
    } else {
        return parseFloat(theValue.toFixed(2));
    }
}

/**
 * 设备图标
 * @param device
 */
function deviceIcon(device) {
    let sensorTypeId = device.sensorTypeId || device.sensor_type_id;
    if (sensorTypeId != undefined) {
        return 'tp-icon-sensor-' + sensorTypeId;
    }
}

/**
 * 传感器值
 * @param sensor
 * @returns {string}
 */
function sensorValue(sensor, key = 'device_value') {
    let {sensor_type_id, precision = 1, sensor_unit = ''} = sensor;
    let value = null;
    if (sensor[key] != undefined && !isNaN(sensor[key])) {
        if (sensor_type_id != 180) {
            value = parseFloat(sensor[key].toFixed(precision));
        } else {
            //风向特殊处理
            return windDirection(sensor[key]);
        }
    } else {
        value = '--';
    }
    return value;
}

/**
 * 根据偏转的角度判断风向（如东风、西北风等）
 * @param dtn
 * @returns {string}
 */
function windDirection(value) {
    let direction = '--';
    if (value != null && value != undefined && !isNaN(value)) {
        let dtn = parseFloat(value);
        if ((dtn >= 337.6 && dtn <= 360) || (dtn >= 0 && dtn <= 22.5)) {
            direction = '北风';
        } else if (dtn >= 22.6 && dtn <= 67.5) {
            direction = '东北风';
        } else if (dtn >= 67.6 && dtn <= 112.5) {
            direction = '东风';
        } else if (dtn >= 112.6 && dtn <= 157.5) {
            direction = '东南风';
        } else if (dtn >= 157.6 && dtn <= 202.5) {
            direction = '南风';
        } else if (dtn >= 202.6 && dtn <= 247.5) {
            direction = '西南风';
        } else if (dtn >= 247.6 && dtn <= 292.5) {
            direction = '西风';
        } else if (dtn >= 292.6 && dtn <= 337.5) {
            direction = '西北风';
        }
    }
    return direction;
}

/**
 * @descript: 图片加载完成后的操作
 * @param  {src}
 * @return {width} 图片实际宽度
 * @return {height} 图片实际高度
 * @return {img} 图片对象
 */
function loadImage(src) {
    return new Promise((resolve, reject) => {
        const img = new Image();
        img.src = src;
        // img.crossOrigin = 'Anonymous'; // ios可能会报错
        img.onload = () => {
            resolve({
                width: img.width,
                height: img.height,
                img
            })
        };
        img.onerror = err => {
            reject(err)
        };
    })
}

/** 通用请求 **/
function request(api, param, method = 'post') {
    return new Promise((resolve, reject) => {
        tpHttp[method](this, `${api}`, {param: JSON.stringify(param || {})}, (data, code, message) => {
                const res = {data, code, message};
                if (code == 0) {
                    resolve(data);
                } else {
                    reject(res);
                }
            }
        );
    });
}

/** 公用api请求 **/
function requestApi(apiAlias, key) {
    const param = {
        apiAlias: apiAlias,
        key: Object.assign({where: '', orderBy: ''}, key),
    };
    return request(`action=com.top.scree.cq.callDcApiByAlias`, param);
}


/**
 * 大屏公用无数据
 * @name dp-no-data
 */
Vue.component('dp-no-data', {
    template: `<div class="dp-no-data" :style="{height:height}">
               <img src="../../resources/img/dp-layout/dp-no-data.png" alt="" :style="{width:width}"> 
               <span>{{title}}</span> 
           </div>`,
    props: {
        title: {type: String, default: '暂无数据'},
        width: {type: String, defualt: '30%'},
        height: {type: String, defualt: 'auto'},
    },

    data() {
        return {};
    },
});